"""PAMR Cross Validate

.. helpdoc::
The PAMR CV widget generates cross vaildated probabilities for call designation from a PAMR Fit and optional PAMR data container.  This uses a k-fold cross validation procedure and will highlight those thresholds which minimize the missclassification error.
"""


"""<widgetXML>
    <name>PAMR Cross Validate</name>
    <icon></icon>
    <tags>
        <tag>PAMR</tag>
    </tags>
    <summary>Cross Validates a PAMR Model Fit.</summary>
    <author>
        <authorname>Red-R Core Development Team</authorname>
        <authorcontact>www.red-r.org</authorcontact>
    </author>
    </widgetXML>
"""

"""
<name>Cross Validate PAMR</name>
<description>The PAMR CV widget generates cross vaildated probabilities for call designation from a PAMR Fit and optional PAMR data container.  This uses a k-fold cross validation procedure and will highlight those thresholds which minimize the missclassification error.</description>
<author>Generated using Widget Maker written by Kyle R. Covington, modifications by Kyle R. Covington kyle@red-r.org</author>
<tags>PAMR</tags>
"""
from OWRpy import * 
import OWGUI 
import redRGUI, signals

## standard qtWidget Import Section
from libraries.base.qtWidgets.scrollArea import scrollArea as redRScrollArea
from libraries.base.qtWidgets.checkBox import checkBox as redRCheckBox
from libraries.base.qtWidgets.comboBox import comboBox as redRComboBox
from libraries.base.qtWidgets.button import button as redRButton
from libraries.base.qtWidgets.textEdit import textEdit as redRTextEdit
from libraries.base.qtWidgets.radioButtons import radioButtons as redRRadioButtons
from libraries.base.qtWidgets.widgetLabel import widgetLabel as redRWidgetLabel
from libraries.base.qtWidgets.fileNamesComboBox import fileNamesComboBox as redRFileNamesCombo
from libraries.base.qtWidgets.groupBox import groupBox as redRGroupBox
from libraries.base.qtWidgets.lineEdit import lineEdit as redRLineEdit
from libraries.base.qtWidgets.widgetBox import widgetBox as redRWidgetBox
from libraries.base.qtWidgets.commitButton import commitButton as redRCommitButton
from libraries.base.qtWidgets.graphicsView import graphicsView as redRGraphicsView

class pamr_cv(OWRpy): 
    settingsList = []
    def __init__(self, **kwargs):
        OWRpy.__init__(self, **kwargs)
        self.require_librarys(["pamr"])
        self.setRvariableNames(["pamr.cv"])
        self.RFunctionParam_folds = "NULL"
        self.RFunctionParam_nfold = "NULL"
        self.RFunctionParam_data = ''
        self.RFunctionParam_fit = ''
        self.require_librarys(["pamr"])
        """.. rrsignlas::"""
        self.inputs.addInput("data", 'PAMR Data Collection (optional)', signals.pamr.RPAMRData, self.processdata)
        
        """.. rrsignlas::"""
        self.inputs.addInput("fit", 'Trained PAMR Model Fit', signals.pamr.RPAMRFit, self.processfit)
        
        """.. rrsignlas::"""
        self.outputs.addOutput("pamr.cv Output", 'Cross Validated PAMR Model Fit', signals.pamr.RPAMRCVFit)

        self.RFunctionParamfolds_lineEdit =  redRLineEdit(self.controlArea,  label = "folds:")
        self.RFunctionParamnfold_lineEdit =  redRLineEdit(self.controlArea,  label = "nfold:")
        self.plotArea = redRGraphicsView(self.controlArea)
        redRCommitButton(self.bottomAreaRight, "Commit", callback = self.commitFunction)
        
        self.R("""
        krc.pamr.plotcvclasserror<-function(fit){
    
    n <- nrow(fit$yhat)
    y <- fit$y
    if (!is.null(fit$newy)) {
        y <- fit$newy[fit$sample.subset]
    }
    
    err2 <- matrix(NA, nrow = length(unique(y)), ncol = length(fit$threshold))
    for (i in 1:(length(fit$threshold) - 1)) {
        s <- pamr.confusion(fit, fit$threshold[i], extra = FALSE)
        diag(s) <- 0
        err2[, i] <- apply(s, 1, sum)/table(y)
    }
    plot(fit$threshold, err2[1, ], ylim = c(-0.1, 1.1), xlab = "Value of threshold ", 
        ylab = "Misclassification Error", type = "n", yaxt = "n")
    axis(3, at = fit$threshold, lab = paste(fit$size), srt = 90, 
        adj = 0)
    axis(2, at = c(0, 0.2, 0.4, 0.6, 0.8))
    for (i in 1:nrow(err2)) {
        lines(fit$threshold, err2[i, ], col = i + 1)
    }
    legend(0, 0.9, dimnames(table(y))[[1]], col = (2:(nc + 1)), 
        lty = 1)
        
    }
        """, wantType = 'NoConversion')
    def processdata(self, data):
        
        if data:
            self.RFunctionParam_data=str(data.getData())
    def processfit(self, data):
        
        if data:
            self.RFunctionParam_fit=str(data.getData())
            self.RFunctionParam_data= data.getOptionalData('parent')['data']
    def commitFunction(self):
        if unicode(self.RFunctionParam_data) == '': 
            self.status.setText('No data to process')
            return
        if unicode(self.RFunctionParam_fit) == '': 
            self.status.setText('No data fit to work with')
            return
        injection = []
        if unicode(self.RFunctionParamfolds_lineEdit.text()) != '':
            string = 'folds='+unicode(self.RFunctionParamfolds_lineEdit.text())
            injection.append(string)
        if unicode(self.RFunctionParamnfold_lineEdit.text()) != '':
            string = 'nfold='+unicode(self.RFunctionParamnfold_lineEdit.text())
            injection.append(string)
        inj = ','.join(injection)
        self.R(self.Rvariables['pamr.cv']+'<-pamr.cv(data='+unicode(self.RFunctionParam_data)+',fit='+unicode(self.RFunctionParam_fit)+','+inj+')')
        #self.R('pamr.plotcv('+self.Rvariables['pamr.cv']+')')
        newData = signals.pamr.RPAMRCVFit(self, data = self.Rvariables['pamr.cv'])
        self.rSend("pamr.cv Output", newData)
        
        self.plotArea.plot(function = 'pamr.plotcv', query = 'fit='+self.Rvariables['pamr.cv'])


